package nc.bs.common.util;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * @author cloudwxjj
 * @date 2024/4/19-上午11:08
 */
public class SQLUtil {

    public static String buildInCondition(String key, String[] values) {
        StringBuilder sb = new StringBuilder();
        sb.append(key).append(" in (");
        for (String s : values) {
            sb.append("'").append(s).append("',");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append(")");
        return sb.toString();
    }

    public static String buildOrCondition(String key, String[] values) {
        return buildOrNotCondition(key,values,false);
    }

    public static String buildOrNotCondition(String key, String[] values,boolean not) {
        StringBuilder sb = new StringBuilder();
        sb.append("(");
        String ifc = !not ? " in (" : " not in (";
        sb.append("substr(").append(key).append(",0,").append(values[0].length()).append(")").append(ifc);
        for (String value : values) {
            sb.append("'").append(value).append("',");
        }
        sb.deleteCharAt(sb.length() - 1);
        sb.append("))");
        return sb.toString();
    }

    public static String selectToString(String[] selectColumns) {
        StringBuilder sb = new StringBuilder();
        for (String c : selectColumns) {
            sb.append(c).append(",");
        }
        sb.deleteCharAt(sb.length() - 1);
        return sb.toString();
    }

    public static String whereToString(Map<String, String[]> condition) {
        return whereToString(false,condition);
    }

    public static String whereNotToString(Map<String, String[]> condition) {
        return whereToString(true,condition);
    }

// oracle 中 in 长度最长为1000 操作会报错，进行优化
//    private static String whereToString(boolean not ,Map<String, String[]> condition) {
//        String ifg = !not ? " in " : " not in ";
//        StringBuilder sb = new StringBuilder();
//        sb.append(" 1 = 1 ");
//        for (Map.Entry<String, String[]> entry : condition.entrySet()) {
//            sb.append(" and ");
//            String k = entry.getKey();
//            Object v = entry.getValue();
//            sb.append(k).append(" ").append(ifg).append(" (");
//            if (v instanceof String[]) {
//                for (String s : (String[]) v) {
//                    sb.append("'").append(s).append("',");
//                }
//            } else {
//                for (Object s : (Object[]) v) {
//                    sb.append("'").append(s).append("',");
//                }
//            }
//            sb.deleteCharAt(sb.length() - 1);
//            sb.append(")");
//
//        }
//        return sb.toString();
//    }

    private static String whereToString(boolean not , Map<String, String[]> condition) {
        String ifg = !not ? " in " : " not in ";
        StringBuilder sb = new StringBuilder();
        sb.append(" 1 = 1 ");
        for (Map.Entry<String, String[]> entry : condition.entrySet()) {
            sb.append(" and ");
            String k = entry.getKey();
            Object v = entry.getValue();
            sb.append(k).append(" ").append(ifg).append(" (");
            if (v instanceof String[]) {
                String[] vs = (String[]) v;
                sb = batchSQL(sb, vs);
            } else {
                Object[] vs = (Object[]) v;
                sb = batchSQL(sb, vs);
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.append(")");

        }
        return sb.toString();
    }

    /**
     * 由于Oracle中 in 的长度最长为1000 所以进行优化 没 900 一组
     * @param sb  拼接之前的 SQL  格式  1 = 1 and sql in (
     * @param obj
     * @return
     */
    public static StringBuilder batchSQL(StringBuilder sb, Object[] obj) {
        List<Object> lists = Arrays.stream(obj).toList();
        List<List<Object>> batch = batch(lists, 900 ); // oracle in 中值最长为1000
        String sql = " and " + sb;
        StringBuilder inSQL = new StringBuilder();
        for (int i = 0; i < batch.size(); i++) {
            StringBuilder sp = new StringBuilder();
            if(i != 0 ){
                sp.append( sql );
            }
            List<Object> rows = batch.get(i);
            for (Object row : rows) {
                sp.append("'").append(row).append("',");
            }
            if (i < batch.size() - 1) {
                sp.deleteCharAt(sp.length() - 1);
                sp.append(")");
            }
            inSQL.append(sp);
        }
        sb.append(inSQL);
        return sb;
    }

    /**
     * 将 List 进行分组  按照  batchSize 的大小进行分组
     * @param list      需要分组的  List<T>
     * @param batchSize 分组长度
     * @return
     * @param <T>
     */
    public static <T> List<List<T>> batch(List<T> list, int batchSize) {
        return IntStream.range(0, (list.size() + batchSize - 1) / batchSize)
                .mapToObj(i -> list.subList(i * batchSize, Math.min((i + 1) * batchSize, list.size())))
                .collect(Collectors.toList());
    }
}
